home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir24 / jnos110g.zip / TCPIN.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  31KB  |  930 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  *
  6.  * Mods by PA0GRI (access control)
  7.  * Copyright 1992 Gerard J van der Grinten, PA0GRI
  8.  */
  9. #include "global.h"
  10. #include "timer.h"
  11. #include "mbuf.h"
  12. #include "netuser.h"
  13. #include "internet.h"
  14. #include "iface.h"
  15. #include "tcp.h"
  16. #include "icmp.h"
  17. #include "iface.h"
  18. #include "ip.h"
  19.   
  20. static void update __ARGS((struct tcb *tcb,struct tcp *seg,int16 length));
  21. static void proc_syn __ARGS((struct tcb *tcb,char tos,struct tcp *seg));
  22. static void add_reseq __ARGS((struct tcb *tcb,char tos,struct tcp *seg,
  23. struct mbuf *bp,int16 length));
  24. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  25. struct mbuf **bp,int16 *length));
  26. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  27. int16 *length));
  28. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  29.   
  30. /* This function is called from IP with the IP header in machine byte order,
  31.  * along with a mbuf chain pointing to the TCP header.
  32.  */
  33. void
  34. tcp_input(iface,ip,bp,rxbroadcast)
  35. struct iface *iface;    /* Incoming interface (ignored) */
  36. struct mbuf *bp;    /* Data field, if any */
  37. struct ip *ip;      /* IP header */
  38. int rxbroadcast;    /* Incoming broadcast - discard if true */
  39. {
  40.     struct tcb *ntcb;
  41.     struct tcb *tcb;   /* TCP Protocol control block */
  42.     struct tcp seg;         /* Local copy of segment header */
  43.     struct connection conn;     /* Local copy of addresses */
  44.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  45.     int hdrlen;         /* Length of TCP header */
  46.     int16 length;
  47.   
  48.     if(bp == NULLBUF)
  49.         return;
  50.   
  51.     tcpInSegs++;
  52.     if(rxbroadcast){
  53.         /* Any TCP packet arriving as a broadcast is
  54.          * to be completely IGNORED!!
  55.          */
  56.         free_p(bp);
  57.         return;
  58.     }
  59.     length = ip->length - IPLEN - ip->optlen;
  60.     ph.source = ip->source;
  61.     ph.dest = ip->dest;
  62.     ph.protocol = ip->protocol;
  63.     ph.length = length;
  64.     if(cksum(&ph,bp,length) != 0){
  65.         /* Checksum failed, ignore segment completely */
  66.         tcpInErrs++;
  67.         free_p(bp);
  68.         return;
  69.     }
  70.     /* Form local copy of TCP header in host byte order */
  71.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  72.         /* TCP header is too small */
  73.         free_p(bp);
  74.         return;
  75.     }
  76.     length -= hdrlen;
  77.   
  78.     /* Fill in connection structure and find TCB */
  79.     conn.local.address = ip->dest;
  80.     conn.local.port = seg.dest;
  81.     conn.remote.address = ip->source;
  82.     conn.remote.port = seg.source;
  83.   
  84.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  85.         /* If memory low, reject it - WG7J */
  86.         /* If this segment doesn't carry a SYN, reject it */
  87.         if((availmem() < Memthresh) || !seg.flags.syn){
  88.             free_p(bp);
  89.             reset(ip,&seg);
  90.             return;
  91.         }
  92. #ifdef  TCPACCESS
  93.         if(tcp_check(TCPaccess,ip->source,seg.dest) != 0 ) {
  94.             free_p(bp);
  95.             reset(ip,&seg);
  96.             return;
  97.         }
  98. #endif
  99.         /* See if there's a TCP_LISTEN on this socket with
  100.          * unspecified remote address and port
  101.          */
  102.         conn.remote.address = 0;
  103.         conn.remote.port = 0;
  104.         /* NOS currently always listens on unspecified addresses ! - WG7J */
  105.         conn.local.address = 0;
  106.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  107.             /* No LISTENs, so reject */
  108.             free_p(bp);
  109.             reset(ip,&seg);
  110.             return;
  111.         }
  112.         /* We've found an server listen socket, so clone the TCB */
  113.         if(tcb->flags.clone){
  114.             ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  115.             ASSIGN(*ntcb,*tcb);
  116.             tcb = ntcb;
  117.             tcb->timer.arg = tcb;
  118.             /* Put on list */
  119.             tcb->next = Tcbs;
  120.             Tcbs = tcb;
  121.         }
  122.         /* Put all the socket info into the TCB */
  123.         tcb->conn.local.address = ip->dest;
  124.         tcb->conn.remote.address = ip->source;
  125.         tcb->conn.remote.port = seg.source;
  126.   
  127.         /* Now point to the tcp interface specific parameters if
  128.          * none set. This is only needed for incoming connections.
  129.          * Outgoing ones get the pointer set in open_tcp() - WG7J
  130.          */
  131.         tcb->parms = iface->tcp;
  132.   
  133.         /* Find a known rtt or load interface default */
  134.         set_irtt(tcb);
  135.     }
  136.   
  137.     tcb->flags.congest = ip->flags.congest;
  138.     /* Do unsynchronized-state processing (p. 65-68) */
  139.     switch(tcb->state){
  140.         case TCP_CLOSED:
  141.             free_p(bp);
  142.             reset(ip,&seg);
  143.             return;
  144.         case TCP_LISTEN:
  145.             if(seg.flags.rst){
  146.                 free_p(bp);
  147.                 return;
  148.             }
  149.             if(seg.flags.ack){
  150.                 free_p(bp);
  151.                 reset(ip,&seg);
  152.                 return;
  153.             }
  154.             if(seg.flags.syn){
  155.             /* (Security check is bypassed) */
  156.             /* page 66 */
  157.                 proc_syn(tcb,ip->tos,&seg);
  158.                 send_syn(tcb);
  159.                 setstate(tcb,TCP_SYN_RECEIVED);
  160.                 if(length != 0 || seg.flags.fin) {
  161.                 /* Continue processing if there's more */
  162.                     break;
  163.                 }
  164.                 tcp_output(tcb);
  165.             }
  166.             free_p(bp); /* Unlikely to get here directly */
  167.             return;
  168.         case TCP_SYN_SENT:
  169.             if(seg.flags.ack){
  170.                 if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  171.                     free_p(bp);
  172.                     reset(ip,&seg);
  173.                     return;
  174.                 }
  175.             }
  176.             if(seg.flags.rst){  /* p 67 */
  177.                 if(seg.flags.ack){
  178.                 /* The ack must be acceptable since we just checked it.
  179.                  * This is how the remote side refuses connect requests.
  180.                  */
  181.                     close_self(tcb,RESET);
  182.                 }
  183.                 free_p(bp);
  184.                 return;
  185.             }
  186.         /* (Security check skipped here) */
  187. #ifdef  PREC_CHECK  /* Turned off for compatibility with BSD */
  188.         /* Check incoming precedence; it must match if there's an ACK */
  189.             if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  190.                 free_p(bp);
  191.                 reset(ip,&seg);
  192.                 return;
  193.             }
  194. #endif
  195.             if(seg.flags.syn){
  196.                 proc_syn(tcb,ip->tos,&seg);
  197.                 if(seg.flags.ack){
  198.                 /* Our SYN has been acked, otherwise the ACK
  199.                  * wouldn't have been valid.
  200.                  */
  201.                     update(tcb,&seg,length);
  202.                     setstate(tcb,TCP_ESTABLISHED);
  203.                 } else {
  204.                     setstate(tcb,TCP_SYN_RECEIVED);
  205.                 }
  206.                 if(length != 0 || seg.flags.fin) {
  207.                     break;      /* Continue processing if there's more */
  208.                 }
  209.                 tcp_output(tcb);
  210.             } else {
  211.                 free_p(bp); /* Ignore if neither SYN or RST is set */
  212.             }
  213.             return;
  214.     }
  215.     /* We reach this point directly in any synchronized state. Note that
  216.      * if we fell through from LISTEN or SYN_SENT processing because of a
  217.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  218.      */
  219.   
  220.     /* Trim segment to fit receive window. */
  221.     if(trim(tcb,&seg,&bp,&length) == -1){
  222.         /* Segment is unacceptable */
  223.         if(!seg.flags.rst){ /* NEVER answer RSTs */
  224.             /* In SYN_RECEIVED state, answer a retransmitted SYN
  225.              * with a retransmitted SYN/ACK.
  226.              */
  227.             if(tcb->state == TCP_SYN_RECEIVED)
  228.                 tcb->snd.ptr = tcb->snd.una;
  229.             tcb->flags.force = 1;
  230.             tcp_output(tcb);
  231.         }
  232.         return;
  233.     }
  234.     /* If segment isn't the next one expected, and there's data
  235.      * or flags associated with it, put it on the resequencing
  236.      * queue, ACK it and return.
  237.      *
  238.      * Processing the ACK in an out-of-sequence segment without
  239.      * flags or data should be safe, however.
  240.      */
  241.     if(seg.seq != tcb->rcv.nxt
  242.     && (length != 0 || seg.flags.syn || seg.flags.fin)){
  243.         add_reseq(tcb,ip->tos,&seg,bp,length);
  244.         tcb->flags.force = 1;
  245.         tcp_output(tcb);
  246.         return;
  247.     }
  248.     /* This loop first processes the current segment, and then
  249.      * repeats if it can process the resequencing queue.
  250.      */
  251.     for(;;){
  252.         /* We reach this point with an acceptable segment; all data and flags
  253.          * are in the window, and the starting sequence number equals rcv.nxt
  254.          * (p. 70)
  255.          */
  256.         if(seg.flags.rst){
  257.             if(tcb->state == TCP_SYN_RECEIVED
  258.             && !tcb->flags.clone && !tcb->flags.active){
  259.                 /* Go back to listen state only if this was
  260.                  * not a cloned or active server TCB
  261.                  */
  262.                 setstate(tcb,TCP_LISTEN);
  263.             } else {
  264.                 close_self(tcb,RESET);
  265.             }
  266.             free_p(bp);
  267.             return;
  268.         }
  269.         /* (Security check skipped here) p. 71 */
  270. #ifdef  PREC_CHECK
  271.         /* Check for precedence mismatch */
  272.         if(PREC(ip->tos) != PREC(tcb->tos)){
  273.             free_p(bp);
  274.             reset(ip,&seg);
  275.             return;
  276.         }
  277. #endif
  278.         /* Check for erroneous extra SYN */
  279.         if(seg.flags.syn){
  280.             free_p(bp);
  281.             reset(ip,&seg);
  282.             return;
  283.         }
  284.         /* Check ack field p. 72 */
  285.         if(!seg.flags.ack){
  286.             free_p(bp); /* All segments after synchronization must have ACK */
  287.             return;
  288.         }
  289.         /* Process ACK */
  290.         switch(tcb->state){
  291.             case TCP_SYN_RECEIVED:
  292.                 if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  293.                     update(tcb,&seg,length);
  294.                     setstate(tcb,TCP_ESTABLISHED);
  295.                 } else {
  296.                     free_p(bp);
  297.                     reset(ip,&seg);
  298.                     return;
  299.                 }
  300.                 break;
  301.             case TCP_ESTABLISHED:
  302.             case TCP_CLOSE_WAIT:
  303.                 update(tcb,&seg,length);
  304.                 break;
  305.             case TCP_FINWAIT1:  /* p. 73 */
  306.                 update(tcb,&seg,length);
  307.                 if(tcb->sndcnt == 0){
  308.                 /* Our FIN is acknowledged */
  309.                     setstate(tcb,TCP_FINWAIT2);
  310.                 }
  311.                 break;
  312.             case TCP_FINWAIT2:
  313.                 update(tcb,&seg,length);
  314.                 break;
  315.             case TCP_CLOSING:
  316.                 update(tcb,&seg,length);
  317.                 if(tcb->sndcnt == 0){
  318.                 /* Our FIN is acknowledged */
  319.                     setstate(tcb,TCP_TIME_WAIT);
  320.                     set_timer(&tcb->timer,MSL2*1000L);
  321.                     start_timer(&tcb->timer);
  322.                 }
  323.                 break;
  324.             case TCP_LAST_ACK:
  325.                 update(tcb,&seg,length);
  326.                 if(tcb->sndcnt == 0){
  327.                 /* Our FIN is acknowledged, close connection */
  328.                     close_self(tcb,NORMAL);
  329.                     return;
  330.                 }
  331.                 break;
  332.             case TCP_TIME_WAIT:
  333.                 start_timer(&tcb->timer);
  334.                 break;
  335.         }
  336.   
  337.         /* (URGent bit processing skipped here) */
  338.   
  339.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  340.         if(length != 0){
  341.             switch(tcb->state){
  342.                 case TCP_SYN_RECEIVED:
  343.                 case TCP_ESTABLISHED:
  344.                 case TCP_FINWAIT1:
  345.                 case TCP_FINWAIT2:
  346.                 /* Place on receive queue */
  347.                     append(&tcb->rcvq,bp);
  348.                     tcb->rcvcnt += length;
  349.                     tcb->rcv.nxt += length;
  350.                     tcb->rcv.wnd -= length;
  351.                     tcb->flags.force = 1;
  352.                 /* Notify user */
  353.                     if(tcb->r_upcall)
  354.                         (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  355.                     break;
  356.                 default:
  357.                 /* Ignore segment text */
  358.                     free_p(bp);
  359.                     break;
  360.             }
  361.         }
  362.         /* process FIN bit (p 75) */
  363.         if(seg.flags.fin){
  364.             tcb->flags.force = 1;   /* Always respond with an ACK */
  365.   
  366.             switch(tcb->state){
  367.                 case TCP_SYN_RECEIVED:
  368.                 case TCP_ESTABLISHED:
  369.                     tcb->rcv.nxt++;
  370.                     setstate(tcb,TCP_CLOSE_WAIT);
  371.                     break;
  372.                 case TCP_FINWAIT1:
  373.                     tcb->rcv.nxt++;
  374.                     if(tcb->sndcnt == 0){
  375.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  376.                         setstate(tcb,TCP_TIME_WAIT);
  377.                         set_timer(&tcb->timer,MSL2*1000L);
  378.                         start_timer(&tcb->timer);
  379.                     } else {
  380.                         setstate(tcb,TCP_CLOSING);
  381.                     }
  382.                     break;
  383.                 case TCP_FINWAIT2:
  384.                     tcb->rcv.nxt++;
  385.                     setstate(tcb,TCP_TIME_WAIT);
  386.                     set_timer(&tcb->timer,MSL2*1000L);
  387.                     start_timer(&tcb->timer);
  388.                     break;
  389.                 case TCP_CLOSE_WAIT:
  390.                 case TCP_CLOSING:
  391.                 case TCP_LAST_ACK:
  392.                     break;      /* Ignore */
  393.                 case TCP_TIME_WAIT: /* p 76 */
  394.                     start_timer(&tcb->timer);
  395.                     break;
  396.             }
  397.             /* Call the client again so he can see EOF */
  398.             if(tcb->r_upcall)
  399.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  400.         }
  401.         /* Scan the resequencing queue, looking for a segment we can handle,
  402.          * and freeing all those that are now obsolete.
  403.          */
  404.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  405.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  406.             if(trim(tcb,&seg,&bp,&length) == 0)
  407.                 goto gotone;
  408.             /* Segment is an old one; trim has freed it */
  409.         }
  410.         break;
  411.         gotone: ;
  412.     }
  413.     tcp_output(tcb);    /* Send any necessary ack */
  414. }
  415.   
  416. /* Process an incoming ICMP response */
  417. void
  418. tcp_icmp(icsource,source,dest,type,code,bpp)
  419. int32 icsource;         /* Sender of ICMP message (not used) */
  420. int32 source;           /* Original IP datagram source (i.e. us) */
  421. int32 dest;         /* Original IP datagram dest (i.e., them) */
  422. char type,code;         /* ICMP error codes */
  423. struct mbuf **bpp;      /* First 8 bytes of TCP header */
  424. {
  425.     struct tcp seg;
  426.     struct connection conn;
  427.     register struct tcb *tcb;
  428.   
  429.     /* Extract the socket info from the returned TCP header fragment
  430.      * Note that since this is a datagram we sent, the source fields
  431.      * refer to the local side.
  432.      */
  433.     ntohtcp(&seg,bpp);
  434.     conn.local.port = seg.source;
  435.     conn.remote.port = seg.dest;
  436.     conn.local.address = source;
  437.     conn.remote.address = dest;
  438.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  439.         return; /* Unknown connection, ignore */
  440.   
  441.     /* Verify that the sequence number in the returned segment corresponds
  442.      * to something currently unacknowledged. If not, it can safely
  443.      * be ignored.
  444.      */
  445.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  446.         return;
  447.   
  448.     /* Destination Unreachable and Time Exceeded messages never kill a
  449.      * connection; the info is merely saved for future reference.
  450.      */
  451.     switch(uchar(type)){
  452.         case ICMP_DEST_UNREACH:
  453.         case ICMP_TIME_EXCEED:
  454.             tcb->type = type;
  455.             tcb->code = code;
  456.             break;
  457.         case ICMP_QUENCH:
  458.          /* Source quench; reduce slowstart threshold to half
  459.          * current window and restart slowstart
  460.          */
  461.             tcb->ssthresh = tcb->cwind / 2;
  462.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  463.         /* Shrink congestion window to 1 packet */
  464.             tcb->cwind = tcb->mss;
  465.             break;
  466.     }
  467. }
  468. /* Send an acceptable reset (RST) response for this segment
  469.  * The RST reply is composed in place on the input segment
  470.  */
  471. void
  472. reset(ip,seg)
  473. struct ip *ip;          /* Offending IP header */
  474. register struct tcp *seg;   /* Offending TCP header */
  475. {
  476.     struct mbuf *hbp;
  477.     struct pseudo_header ph;
  478.     int16 tmp;
  479.   
  480.     if(seg->flags.rst)
  481.         return; /* Never send an RST in response to an RST */
  482.   
  483.     /* Compose the RST IP pseudo-header, swapping addresses */
  484.     ph.source = ip->dest;
  485.     ph.dest = ip->source;
  486.     ph.protocol = TCP_PTCL;
  487.     ph.length = TCPLEN;
  488.   
  489.     /* Swap port numbers */
  490.     tmp = seg->source;
  491.     seg->source = seg->dest;
  492.     seg->dest = tmp;
  493.   
  494.     if(seg->flags.ack){
  495.         /* This reset is being sent to clear a half-open connection.
  496.          * Set the sequence number of the RST to the incoming ACK
  497.          * so it will be acceptable.
  498.          */
  499.         seg->flags.ack = 0;
  500.         seg->seq = seg->ack;
  501.         seg->ack = 0;
  502.     } else {
  503.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  504.          * so we have to "acknowledge" their SYN.
  505.          */
  506.         seg->flags.ack = 1;
  507.         seg->ack = seg->seq;
  508.         seg->seq = 0;
  509.         if(seg->flags.syn)
  510.             seg->ack++;
  511.     }
  512.     /* Set remaining parts of packet */
  513.     seg->flags.urg = 0;
  514.     seg->flags.psh = 0;
  515.     seg->flags.rst = 1;
  516.     seg->flags.syn = 0;
  517.     seg->flags.fin = 0;
  518.     seg->wnd = 0;
  519.     seg->up = 0;
  520.     seg->mss = 0;
  521.     seg->optlen = 0;
  522.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  523.         return;
  524.     /* Ship it out (note swap of addresses) */
  525.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  526.     tcpOutRsts++;
  527. }
  528.   
  529. /* Process an incoming acknowledgement and window indication.
  530.  * From page 72.
  531.  */
  532. static void
  533. update(tcb,seg,length)
  534. register struct tcb *tcb;
  535. register struct tcp *seg;
  536. int16 length;
  537. {
  538.     int16 acked;
  539.     int16 expand;
  540.   
  541.     acked = 0;
  542.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  543.         tcb->flags.force = 1;   /* Acks something not yet sent */
  544.         return;
  545.     }
  546.     /* Decide if we need to do a window update.
  547.      * This is always checked whenever a legal ACK is received,
  548.      * even if it doesn't actually acknowledge anything,
  549.      * because it might be a spontaneous window reopening.
  550.      */
  551.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1)
  552.     && seq_ge(seg->ack,tcb->snd.wl2))){
  553.         /* If the window had been closed, crank back the
  554.          * send pointer so we'll immediately resume transmission.
  555.          * Otherwise we'd have to wait until the next probe.
  556.          */
  557.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  558.             tcb->snd.ptr = tcb->snd.una;
  559.         tcb->snd.wnd = seg->wnd;
  560.         tcb->snd.wl1 = seg->seq;
  561.         tcb->snd.wl2 = seg->ack;
  562.     }
  563.     /* See if anything new is being acknowledged */
  564.     if(!seq_gt(seg->ack,tcb->snd.una)){
  565.         if(seg->ack != tcb->snd.una)
  566.             return; /* Old ack, ignore */
  567.   
  568.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  569.             return; /* Nothing acked, but there is data */
  570.   
  571.         /* Van Jacobson "fast recovery" code */
  572.         if(++tcb->dupacks == TCPDUPACKS){
  573.             /* We've had a burst of do-nothing acks, so
  574.              * we almost certainly lost a packet.
  575.              * Resend it now to avoid a timeout. (This is
  576.              * Van Jacobson's 'quick recovery' algorithm.)
  577.              */
  578.             int32 ptrsave;
  579.   
  580.             /* Knock the threshold down just as though
  581.              * this were a timeout, since we've had
  582.              * network congestion.
  583.              */
  584.             tcb->ssthresh = tcb->cwind/2;
  585.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  586.   
  587.             /* Manipulate the machinery in tcp_output() to
  588.              * retransmit just the missing packet
  589.              */
  590.             ptrsave = tcb->snd.ptr;
  591.             tcb->snd.ptr = tcb->snd.una;
  592.             tcb->cwind = tcb->mss;
  593.             tcp_output(tcb);
  594.             tcb->snd.ptr = ptrsave;
  595.   
  596.             /* "Inflate" the congestion window, pretending as
  597.              * though the duplicate acks were normally acking
  598.              * the packets beyond the one that was lost.
  599.              */
  600.             tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  601.         } else if(tcb->dupacks > TCPDUPACKS){
  602.             /* Continue to inflate the congestion window
  603.              * until the acks finally get "unstuck".
  604.              */
  605.             tcb->cwind += tcb->mss;
  606.         }
  607.         return;
  608.     }
  609.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  610.         /* The acks have finally gotten "unstuck". So now we
  611.          * can "deflate" the congestion window, i.e. take it
  612.          * back down to where it would be after slow start
  613.          * finishes.
  614.          */
  615.         tcb->cwind = tcb->ssthresh;
  616.     }
  617.     tcb->dupacks = 0;
  618.   
  619.     /* We're here, so the ACK must have actually acked something */
  620.     acked = seg->ack - tcb->snd.una;
  621.   
  622.     /* Expand congestion window if not already at limit and if
  623.      * this packet wasn't retransmitted
  624.      */
  625.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  626.         if(tcb->cwind < tcb->ssthresh){
  627.             /* Still doing slow start/CUTE, expand by amount acked */
  628.             expand = min(acked,tcb->mss);
  629.         } else {
  630.             /* Steady-state test of extra path capacity */
  631.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  632.         }
  633.         /* Guard against arithmetic overflow */
  634.         if(tcb->cwind + expand < tcb->cwind)
  635.             expand = MAXINT16 - tcb->cwind;
  636.   
  637.         /* Don't expand beyond the offered window */
  638.         if(tcb->cwind + expand > tcb->snd.wnd)
  639.             expand = tcb->snd.wnd - tcb->cwind;
  640.   
  641.         if(expand != 0){
  642. #ifdef  notdef
  643.             /* Kick up the mean deviation estimate to prevent
  644.              * unnecessary retransmission should we already be
  645.              * bandwidth limited
  646.              */
  647.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  648. #endif
  649.             tcb->cwind += expand;
  650.         }
  651.     }
  652.     /* Round trip time estimation */
  653.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  654.         /* A timed sequence number has been acked */
  655.         tcb->flags.rtt_run = 0;
  656.         if(!(tcb->flags.retran)){
  657.             int32 rtt;  /* measured round trip time */
  658.             int32 abserr;   /* abs(rtt - srtt) */
  659.   
  660.             /* This packet was sent only once and now
  661.              * it's been acked, so process the round trip time
  662.              */
  663.             rtt = msclock() - tcb->rtt_time;
  664.   
  665.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  666.             /* Run SRTT and MDEV integrators, with rounding */
  667.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  668.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  669.   
  670.             rtt_add(tcb->conn.remote.address,rtt);
  671.             /* Reset the backoff level */
  672.             tcb->backoff = 0;
  673.         }
  674.     }
  675.     tcb->sndcnt -= acked;   /* Update virtual byte count on snd queue */
  676.     tcb->snd.una = seg->ack;
  677.   
  678.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  679.     if(!(tcb->flags.synack)){
  680.         tcb->flags.synack = 1;
  681.         acked--;    /* One less byte to pull from real snd queue */
  682.     }
  683.     /* Remove acknowledged bytes from the send queue and update the
  684.      * unacknowledged pointer. If a FIN is being acked,
  685.      * pullup won't be able to remove it from the queue, but that
  686.      * causes no harm.
  687.      */
  688.     pullup(&tcb->sndq,NULLCHAR,acked);
  689.   
  690.     /* Stop retransmission timer, but restart it if there is still
  691.      * unacknowledged data. If there is no more unacked data,
  692.      * the transmitter has gone at least momentarily idle, so
  693.      * record the time for the VJ restart-slowstart rule.
  694.      */
  695.     stop_timer(&tcb->timer);
  696.     if(tcb->snd.una != tcb->snd.nxt)
  697.         start_timer(&tcb->timer);
  698.     else
  699.         tcb->lastactive = msclock();
  700.   
  701.     /* If retransmissions have been occurring, make sure the
  702.      * send pointer doesn't repeat ancient history
  703.      */
  704.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  705.         tcb->snd.ptr = tcb->snd.una;
  706.   
  707.     /* Clear the retransmission flag since the oldest
  708.      * unacknowledged segment (the only one that is ever retransmitted)
  709.      * has now been acked.
  710.      */
  711.     tcb->flags.retran = 0;
  712.   
  713.     /* If outgoing data was acked, notify the user so he can send more
  714.      * unless we've already sent a FIN.
  715.      */
  716.     if(acked != 0 && tcb->t_upcall
  717.     && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)){
  718.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  719.     }
  720. }
  721.   
  722. /* Determine if the given sequence number is in our receiver window.
  723.  * NB: must not be used when window is closed!
  724.  */
  725. static
  726. int
  727. in_window(tcb,seq)
  728. struct tcb *tcb;
  729. int32 seq;
  730. {
  731.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  732. }
  733.   
  734. /* Process an incoming SYN */
  735. static void
  736. proc_syn(tcb,tos,seg)
  737. struct tcb *tcb;
  738. char tos;
  739. struct tcp *seg;
  740. {
  741.     int16 mtu;
  742.     struct tcp_rtt *tp;
  743.     struct iftcp *parms = tcb->parms;
  744.   
  745.     tcb->flags.force = 1;   /* Always send a response */
  746.   
  747.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  748.      * SND.WND are initialized here since it's possible for the
  749.      * window update routine in update() to fail depending on the
  750.      * IRS if they are left unitialized.
  751.      */
  752.     /* Check incoming precedence and increase if higher */
  753.     if(PREC(tos) > PREC(tcb->tos))
  754.         tcb->tos = tos;
  755.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  756.     tcb->snd.wl1 = tcb->irs = seg->seq;
  757.     tcb->snd.wnd = seg->wnd;
  758.     if(seg->mss != 0)
  759.         tcb->mss = seg->mss;
  760.     /* Check the MTU of the interface we'll use to reach this guy
  761.      * and lower the MSS so that unnecessary fragmentation won't occur
  762.      */
  763.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  764.         /* Allow space for the TCP and IP headers */
  765.         mtu -= TCPLEN + IPLEN;
  766.         /* Find the minimum of the mss received, the mtu for the interface,
  767.          * AND the mss set for the interface ! - WG7J
  768.          */
  769.         mtu = min(mtu,parms->mss);
  770.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  771.     }
  772.     /* Set the window size to the incoming interface value */
  773.     tcb->window = tcb->rcv.wnd = parms->window;
  774.   
  775.     /* See if there's round-trip time experience */
  776.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  777.         tcb->srtt = tp->srtt;
  778.         tcb->mdev = tp->mdev;
  779.     } else
  780.         tcb->srtt = parms->irtt;
  781. }
  782.   
  783. /* Generate an initial sequence number and put a SYN on the send queue */
  784. void
  785. send_syn(tcb)
  786. struct tcb *tcb;
  787. {
  788.     tcb->iss = geniss();
  789.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  790.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  791.     tcb->sndcnt++;
  792.     tcb->flags.force = 1;
  793. }
  794.   
  795. /* Add an entry to the resequencing queue in the proper place */
  796. static void
  797. add_reseq(tcb,tos,seg,bp,length)
  798. struct tcb *tcb;
  799. char tos;
  800. struct tcp *seg;
  801. struct mbuf *bp;
  802. int16 length;
  803. {
  804.     register struct reseq *rp,*rp1;
  805.   
  806.     /* Allocate reassembly descriptor */
  807.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  808.         /* No space, toss on floor */
  809.         free_p(bp);
  810.         return;
  811.     }
  812.     ASSIGN(rp->seg,*seg);
  813.     rp->tos = tos;
  814.     rp->bp = bp;
  815.     rp->length = length;
  816.   
  817.     /* Place on reassembly list sorting by starting seq number */
  818.     rp1 = tcb->reseq;
  819.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  820.         /* Either the list is empty, or we're less than all other
  821.          * entries; insert at beginning.
  822.          */
  823.         rp->next = rp1;
  824.         tcb->reseq = rp;
  825.     } else {
  826.         /* Find the last entry less than us */
  827.         for(;;){
  828.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  829.                 /* We belong just after this one */
  830.                 rp->next = rp1->next;
  831.                 rp1->next = rp;
  832.                 break;
  833.             }
  834.             rp1 = rp1->next;
  835.         }
  836.     }
  837. }
  838.   
  839. /* Fetch the first entry off the resequencing queue */
  840. static void
  841. get_reseq(tcb,tos,seg,bp,length)
  842. register struct tcb *tcb;
  843. char *tos;
  844. struct tcp *seg;
  845. struct mbuf **bp;
  846. int16 *length;
  847. {
  848.     register struct reseq *rp;
  849.   
  850.     if((rp = tcb->reseq) == NULLRESEQ)
  851.         return;
  852.   
  853.     tcb->reseq = rp->next;
  854.   
  855.     *tos = rp->tos;
  856.     ASSIGN(*seg,rp->seg);
  857.     *bp = rp->bp;
  858.     *length = rp->length;
  859.     free((char *)rp);
  860. }
  861.   
  862. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  863.  * unacceptable.
  864.  */
  865. static int
  866. trim(tcb,seg,bpp,length)
  867. register struct tcb *tcb;
  868. register struct tcp *seg;
  869. struct mbuf **bpp;
  870. int16 *length;
  871. {
  872.     long dupcnt,excess;
  873.     int16 len;      /* Segment length including flags */
  874.     char accept = 0;
  875.   
  876.     len = *length;
  877.     if(seg->flags.syn)
  878.         len++;
  879.     if(seg->flags.fin)
  880.         len++;
  881.   
  882.     /* Acceptability tests */
  883.     if(tcb->rcv.wnd == 0){
  884.         /* Only in-order, zero-length segments are acceptable when
  885.          * our window is closed.
  886.          */
  887.         if(seg->seq == tcb->rcv.nxt && len == 0){
  888.             return 0;   /* Acceptable, no trimming needed */
  889.         }
  890.     } else {
  891.         /* Some part of the segment must be in the window */
  892.         if(in_window(tcb,seg->seq)){
  893.             accept++;   /* Beginning is */
  894.         } else if(len != 0){
  895.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  896.             seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  897.                 accept++;
  898.             }
  899.         }
  900.     }
  901.     if(!accept){
  902.         tcb->rerecv += len; /* Assume all of it was a duplicate */
  903.         free_p(*bpp);
  904.         return -1;
  905.     }
  906.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  907.         tcb->rerecv += dupcnt;
  908.         /* Trim off SYN if present */
  909.         if(seg->flags.syn){
  910.             /* SYN is before first data byte */
  911.             seg->flags.syn = 0;
  912.             seg->seq++;
  913.             dupcnt--;
  914.         }
  915.         if(dupcnt > 0){
  916.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  917.             seg->seq += dupcnt;
  918.             *length -= dupcnt;
  919.         }
  920.     }
  921.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  922.         tcb->rerecv += excess;
  923.         /* Trim right edge */
  924.         *length -= excess;
  925.         trim_mbuf(bpp,*length);
  926.         seg->flags.fin = 0; /* FIN follows last data byte */
  927.     }
  928.     return 0;
  929. }
  930.